package com.springmvc.crud.handler;

import com.springmvc.crud.dao.DepartmentDao;
import com.springmvc.crud.dao.EmployeeDao;
import com.springmvc.crud.entity.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.WebBindingInitializer;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by BF100233 on 2016/8/23.
 */
@Controller
public class EmployeeHandler {

    @Autowired
    private EmployeeDao employeeDao;

    @Autowired
    private DepartmentDao departmentDao;


    @ResponseStatus(value = HttpStatus.OK,reason = "测试")
    @RequestMapping("testResponseStatusExceptionResolver")
    public String testResponseStatusExceptionResolver(@RequestParam("i") int i){
        if (i==13){
            throw new UserNameNotMatchPasswordException();
        }
        System.out.println("testResponseStatusExceptionResolver....");

        return "seccess";
    }

    //-------------------------------------10月11日---------

    /**
     * 1.在 @ExceptionHandler 方法的入参中可以加入 Exception 类型的参数，该参数即对应发生的异常对象。
     * 2.@ExceptionHandler 方法的入参中不能传入 Map. 若希望把异常信息传到页面上，需要使用 ModelAndView 作为返回值。
     * 3.@ExceptionHandler 方法标记的异常与对应异常相近，有优先级的问题。
     * 4.@ControllerAdvice 如果在当前 Handler 中找不到 @ExceptionHandler 方法来处理当前方法的的异常，
     *   则将去 @ControllerAdvice 标记的类中查找 @ExceptionHandler 标记的方法来处理异常。
     * @param ex
     * @return
     */
//    @ExceptionHandler({RuntimeException.class})
    public ModelAndView handRuntionExecption(Exception ex){
        ModelAndView mv = new ModelAndView("error");
        mv.addObject("exception", ex);
        return mv;
    }

    /**
     * 获取当前类中的异常，进行处理。
     * @param ex2
     * @return
     */
//    @ExceptionHandler({ArithmeticException.class})
    public String handlerArithmeticException(Exception ex2){
        System.out.println("resoult--->:"+ex2);
        return "error";
    }

    @RequestMapping("test")
    public String test(@RequestParam("i") int i){
        System.out.println("resoult:"+(10/i));
        return "seccess";
    }

    //--------------------------------------------------10月10日----

    /**
     * 文件上传
     * @param desc
     * @param file
     * @return
     * @throws IOException
     */
    @RequestMapping("testFileUpload")
    public String testFileUpload(@RequestParam("desc") String desc, @RequestParam("file")MultipartFile file) throws IOException {
        System.out.println("desc:"+desc);
        System.out.println("fileName:" + file.getOriginalFilename());
        System.out.println("InputStream:"+file.getInputStream());
        return "seccess";
    }


    //--------------------------------------------------10月9日

    /**
     * 使用 ResponseEntity 进行文件下载。
     * @param httpSession
     * @return
     */
    @RequestMapping("testResponseEntity")
    public ResponseEntity<byte[]> testResponseEntity(HttpSession httpSession){
//        String str = "我是中国人";
//        byte[] body = str.getBytes();
        byte[] body = null;

        //Idea 使用此方式，无法读取文件
//        ServletContext servletContext = httpSession.getServletContext();
//        InputStream inputStream = servletContext.getResourceAsStream("d:\\Desktop\\info.txt");
        InputStream inputStream = getClass().getResourceAsStream("/info.txt");

        try {
            body = new byte[inputStream.available()];
            inputStream.read(body);
        } catch (IOException e) {
            e.printStackTrace();
        }

        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Disposition","attachment;filename=info.txt");

        HttpStatus statusCode = HttpStatus.OK;

        ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(body, headers, statusCode);
        return responseEntity;
    }

    /**
     * 提交后返回字符串
     * @param Body
     * @return
     */
    @RequestMapping("testHttpMessageConverter")
    public @ResponseBody String testHttpMessageConverter(@RequestBody String Body){
        System.out.println(Body);
        return "holleworld!"+new Date();
    }


    /**
     * ajax 提交后立刻返回 json对象
     * @return
     */
    @RequestMapping("testJson")
    public @ResponseBody Collection<Employee> testJson(){
        return employeeDao.getAll();
    }
//----------------------------------------------10月8日之前----------------
    @RequestMapping(value = "emp",method = RequestMethod.PUT)
    public String update(Employee employee){
        employeeDao.save(employee);
        return "redirect:/emps";
    }

    @RequestMapping(value = "emp/{id}", method = RequestMethod.GET)
    public String input(@PathVariable("id") Integer id,Map<String,Object> map) {
        map.put("employee", employeeDao.get(id));
        map.put("departments", departmentDao.getDepartments());
        return "input";
    }

    @RequestMapping(value = "emp/{id}" ,method = RequestMethod.DELETE)
    public String delete(@PathVariable("id") Integer id) {
        employeeDao.delete(id);
        return "redirect:/emps";
    }

    @RequestMapping(value = "emp",method = RequestMethod.POST)
    public String save(@Valid Employee employee, BindingResult result,Map<String,Object> map){

        if (result.getErrorCount()>0){
            System.out.println("出错了");

            for(FieldError error:result.getFieldErrors()){
                System.out.println(error.getField()+"=="+error.getDefaultMessage());
            }

            //若验证出错，则转向定制页面
            map.put("employee", employee);
            map.put("departments",departmentDao.getDepartments());
            return "input";
        }

        employeeDao.save(employee);
        return "redirect:/emps";
    }

    @RequestMapping(value = "emp",method = RequestMethod.GET)
    public String input(Map<String, Object> map) {
        map.put("employee", new Employee());
        map.put("departments", departmentDao.getDepartments());
        return "input";
    }

    @RequestMapping("emps")
    public String list(Map<String, Object> map) {
        System.out.println(employeeDao.getAll());
        map.put("employees", employeeDao.getAll());
        return "list";
    }

//    @InitBinder
//    public void InitBinder(WebDataBinder binder){
//        binder.setDisallowedFields("lastName");
//    }

}
